package com.remoter.basic.consumer.support;

import java.lang.reflect.Method;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.remoter.basic.bean.support.ConsumerModule;
import com.remoter.basic.bean.support.ProviderModule;
import com.remoter.basic.cluster.ILoadBalance;
import com.remoter.basic.configure.IConfiguration;
import com.remoter.basic.consumer.IConsumer;
import com.remoter.basic.consumer.Invoker;
import com.remoter.basic.util.ServiceLoader;

/**
 * @author			koko
 * @date 			2017-08-09 11:16:44
 * @description 	类功能说明
 */
public abstract class AbstractInvoker implements Invoker{
	
	protected static final Logger logger = LoggerFactory.getLogger(AbstractInvoker.class);
	
	protected IConsumer consumer;
	protected ConsumerModule consumerModule;
	protected abstract Object doInvoke(ProviderModule providerModule,Object proxy, Method method, Object[] args)throws Throwable;
	
	@Override
	public Invoker init(IConfiguration configuration, IConsumer consumer, ConsumerModule consumerModule) throws Exception {
		this.consumer = consumer;
		this.consumerModule = consumerModule;
		return this;
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
		ILoadBalance loadBalance = ServiceLoader.getService(ILoadBalance.class,this.consumerModule.getLoadBalance());
		if(null == loadBalance){
			throw new IllegalStateException("load balance not found");
		}
		List<ProviderModule> providers = this.consumer.getProviders(this.consumerModule);
		ProviderModule providerModule = loadBalance.select(this.consumerModule,providers);
		if(null == providerModule){
			throw new IllegalStateException("provider not found");
		}
		return this.doInvoke(providerModule, proxy, method, args);
	}
	
}